/**
 * API管理器
 * 使用单例模式管理所有API请求
 */

import { APP_CONFIG, API_PATHS, utils } from './config.js'

class ApiManager {
  constructor() {
    // 确保只有一个实例
    if (ApiManager.instance) {
      return ApiManager.instance
    }
    
    // API基础配置
    this.config = {
      baseURL: APP_CONFIG.API_BASE_URL,
      timeout: APP_CONFIG.API_TIMEOUT,
      header: {
        'Content-Type': 'application/json'
      }
    }
    
    // 请求队列，用于管理并发请求
    this.requestQueue = new Map()
    
    // 请求计数器，用于生成唯一ID
    this.requestCounter = 0
    
    ApiManager.instance = this
  }
  
  /**
   * 处理登录重定向
   */
  handleLoginRedirect() {
    console.log('API层检测到登录重定向')
    uni.showModal({
      title: '登录提示',
      content: '登录已过期，请重新登录',
      showCancel: false,
      confirmText: '去登录',
      success: () => {
        // 清除本地存储的登录信息
        uni.removeStorageSync('asurada_user_token')
        uni.removeStorageSync('asurada_user_info')
        
        // 跳转到登录页面
        uni.reLaunch({
          url: '/pages/login/login'
        })
      }
    })
  }
  
  /**
   * 生成唯一请求ID
   */
  generateRequestId() {
    return `req_${++this.requestCounter}_${Date.now()}`
  }
  
  /**
   * 统一请求方法
   * @param {Object} options 请求配置
   */
  request(options) {
    const requestId = this.generateRequestId()
    
    return new Promise((resolve, reject) => {
      // 显示加载提示
      if (options.showLoading !== false) {
        uni.showLoading({
          title: options.loadingText || '请求中...',
          mask: true
        })
      }

      // 获取当前令牌
      const token = uni.getStorageSync('asurada_user_token')
      const headers = {
        ...this.config.header,
        ...options.header
      }
      
      // 添加认证头
      if (token) {
        headers['Authorization'] = `Bearer ${token}`
      }
      headers['X-Refresh-Token'] = uni.getStorageSync('refresh_token')
      headers['X-Im-access-Token'] = uni.getStorageSync('im_access_token')
      headers['X-Im-session-Token'] = uni.getStorageSync('im_session_token')

      // 将请求添加到队列
      this.requestQueue.set(requestId, { options, resolve, reject })

      // 发起请求
      uni.request({
        url: this.config.baseURL + options.url,
        method: options.method || 'GET',
        data: options.data || {},
        header: headers,
        timeout: options.timeout || this.config.timeout,
        withCredentials: true, // 启用Cookie支持
        success: (res) => {
          // 从队列中移除请求
          this.requestQueue.delete(requestId)
          
          // 隐藏加载提示
          if (options.showLoading !== false) {
            uni.hideLoading()
          }

          // 检查是否需要重定向到登录页面
          if (res.statusCode === 200 && typeof res.data === 'string' && res.data.includes('/login')) {
            console.log('API层检测到登录重定向:', res.data)
            this.handleLoginRedirect()
            reject(new Error('需要重新登录'))
            return
          }

          // 处理响应
          if (res.statusCode === 200) {
            const result = res.data
            if (result.code === 200) {
              resolve(result)
            } else {
              // 业务错误
              const errorMsg = result.message || '请求失败'
              // 如果是没有聊天记录，则直接返回，不作为错误处理
              if (errorMsg.includes('没有聊天记录')) {
                resolve(result)
                return
              }
              
              if (options.showError !== false) {
                uni.showToast({
                  title: errorMsg,
                  icon: 'none',
                  duration: 2000
                })
              }
              reject(new Error(errorMsg))
            }
          } else if (res.statusCode === 403) {
            // 处理403 Forbidden错误
            const errorMsg = '访问被拒绝，可能是CORS策略限制或权限不足'
            utils.log('error', '403 Forbidden错误', {
              url: options.url,
              method: options.method || 'GET'
            })
            if (options.showError !== false) {
              uni.showToast({
                title: errorMsg,
                icon: 'none',
                duration: 3000
              })
            }
            reject(new Error(errorMsg))
          } else {
            // 其他HTTP错误
            const errorMsg = `请求失败 (${res.statusCode})`
            if (options.showError !== false) {
              uni.showToast({
                title: errorMsg,
                icon: 'none',
                duration: 2000
              })
            }
            reject(new Error(errorMsg))
          }
        },
        fail: (err) => {
          // 从队列中移除请求
          this.requestQueue.delete(requestId)
          
          // 隐藏加载提示
          if (options.showLoading !== false) {
            uni.hideLoading()
          }

          // 详细的网络错误处理
          let errorMsg = '网络连接失败'
          
          if (err.errMsg) {
            if (err.errMsg.includes('timeout')) {
              errorMsg = '请求超时，请检查网络连接'
            } else if (err.errMsg.includes('fail')) {
              errorMsg = '网络请求失败，请检查服务器状态'
            } else if (err.errMsg.includes('abort')) {
              errorMsg = '请求被取消'
            } else {
              errorMsg = err.errMsg
            }
          }
          
          utils.log('error', '网络请求失败', {
            url: this.config.baseURL + options.url,
            method: options.method || 'GET',
            error: err
          })
          
          if (options.showError !== false) {
            uni.showToast({
              title: errorMsg,
              icon: 'none',
              duration: 3000
            })
          }
          reject(err)
        }
      })
    })
  }
  
  /**
   * GET请求
   */
  get(url, params = {}, options = {}) {
    return this.request({
      url,
      method: 'GET',
      data: params,
      ...options
    })
  }
  
  /**
   * POST请求
   */
  post(url, data = {}, options = {}) {
    return this.request({
      url,
      method: 'POST',
      data,
      ...options
    })
  }
  
  /**
   * PUT请求
   */
  put(url, data = {}, options = {}) {
    return this.request({
      url,
      method: 'PUT',
      data,
      ...options
    })
  }
  
  /**
   * DELETE请求
   */
  del(url, params = {}, options = {}) {
    return this.request({
      url,
      method: 'DELETE',
      data: params,
      ...options
    })
  }
  
  /**
   * 取消所有请求
   */
  cancelAllRequests() {
    this.requestQueue.forEach(({ reject }, requestId) => {
      reject(new Error('请求被取消'))
    })
    this.requestQueue.clear()
  }
  
  /**
   * 获取API配置
   */
  getConfig() {
    return this.config
  }
}

// 导出单例实例
const apiManager = new ApiManager()
export default apiManager

// 导出便捷方法
export const {
  request,
  get,
  post,
  put,
  del
} = apiManager